package com.aigc.sclassroom.ws;


import cn.hutool.json.JSONUtil;
import com.aigc.sclassroom.config.SpringConfigurator;
import com.aigc.sclassroom.pojo.ChatMessage;
import com.aigc.sclassroom.pojo.SysUser;
import com.aigc.sclassroom.service.ChatMessageService;
import com.aigc.sclassroom.service.UserService;
import com.aigc.sclassroom.utils.JwtUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
import jakarta.websocket.*;

import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Component

@ServerEndpoint(value = "/chatroom/{username}", configurator = SpringConfigurator.class)
public class ChatEndpoint {

    //记录日志
    private static final Logger log = LoggerFactory.getLogger(ChatEndpoint.class);
    //存储所有用户的用户名与session
    private static Map<String, Session> onlineUsers = new ConcurrentHashMap<>();


    @Autowired
    private UserService userService;

    @Autowired
    private ChatMessageService chatMessageService;


    @OnOpen
    public void onOpen(Session session, @PathParam("username") String userName) {
        try {
            onlineUsers.put(userName, session);
            log.info("有新用户加入，username={}, 当前在线人数为：{}", userName, onlineUsers.size());
            sendOnlineUsersToAllClients();
        } catch (Exception e) {
            try {
                session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "Error opening session"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }


    @OnMessage
    public void onMessage(String message, Session session, @PathParam("username") String username) {
        log.info("服务端收到用户username={}的消息:{}", username, message);
        JSONObject obj = JSONUtil.parseObj(message);
        String toUsername = obj.getStr("to"); // to表示发送给哪个用户，比如 admin
        String text = obj.getStr("text"); // 发送的消息文本  hello
        // {"to": "admin", "text": "聊天文本"}

        // 保存消息到数据库
        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setSender(username);
        chatMessage.setReceiver(toUsername);
        chatMessage.setMessage(text);
        chatMessageService.saveChatMessage(chatMessage);

        if ("group".equals(toUsername)) {
            // 群聊消息，发送给所有在线用户
            JSONObject groupMessage = new JSONObject();
            groupMessage.set("from", username);
            groupMessage.set("text", text);
            groupMessage.set("to", "group");
            sendAllMessage(groupMessage.toString(), username);
            log.info("群聊消息发送给所有在线用户，消息：{}", groupMessage.toString());
        } else {
            // 私聊消息，执行原有的转发逻辑
            Session toSession = onlineUsers.get(toUsername); // 根据 to用户名来获取 session，再通过session发送消息文本
            if (toSession != null) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.set("from", username);
                jsonObject.set("text", text);
                this.sendMessage(jsonObject.toString(), toSession);
                log.info("发送给用户username={}，消息：{}", toUsername, jsonObject.toString());
            } else {
                log.info("发送失败，未找到用户username={}的session", toUsername);
            }
        }
    }



    @OnClose
    public void onClose(Session session) {
        String userName = findUserNameBySession(session);
        if (userName != null) {
            onlineUsers.remove(userName);
            SysUser sysUser = userService.findByUserName(userName);
            if (sysUser != null) {
                String leaveMessage = sysUser.getUserName() + " 离开了聊天室";
                sendAllMessage(leaveMessage,null);
            }
        }
    }


    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }


    /**
     * 服务端发送消息给客户端
     */
    private void sendMessage(String message, Session toSession) {
        try {
            log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
            toSession.getBasicRemote().sendText(message);
        } catch (Exception e) {
            log.error("服务端发送消息给客户端失败", e);
        }
    }


    private void sendOnlineUsersToAllClients() {
        JSONObject result = new JSONObject();
        JSONArray array = new JSONArray();
        for (String username : onlineUsers.keySet()) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("username", username);
            array.add(jsonObject);
        }
        result.put("users", array);
        sendAllMessage(result.toString(), null);
    }


    /**
     * 服务端发送消息给所有客户端
     * @param message 要发送的消息
     * @param senderUsername 消息发送者的用户名
     */
    private void sendAllMessage(String message, String senderUsername) {
        for (Map.Entry<String, Session> entry : onlineUsers.entrySet()) {
            String username = entry.getKey();
            Session session = entry.getValue();
            // 如果 senderUsername 为 null 或者当前用户不是消息发送者，则发送消息
            if (senderUsername == null ||!username.equals(senderUsername)) {
                log.info("服务端给客户端[{}]发送消息{}", session.getId(), message);
                try {
                    session.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    log.error("服务端发送消息给客户端失败", e);
                }
            }
        }
    }

    private String findUserNameBySession(Session session) {
        for (Map.Entry<String, Session> entry : onlineUsers.entrySet()) {
            if (entry.getValue().equals(session)) {
                return entry.getKey();
            }
        }
        return null;
    }
}
